#include "Object.h"
#include "Integer.h"
#include "Numeric.h"
#include "Float.h"
#include "Types.h"



namespace BaseType
{

uint16_t RTTIOfInfo::classCount = 0;
IntPtr IntPtr::Zero;

static int alloc_count = 0;
static int free_count = 0;

static int allocobj_count = 0;
static int freeobj_count = 0;


const MemberInfo* Object::GetMemberInfo()
{
    return NULL;
}

ImplementRTTIOfClass(Handler, Object)

//========================================================

bool RTTIOfInfo::Equals(RTTIOfInfo* Other) 
{ 
    return this == Other && classIndex == Other->classIndex; 
}

Object::Object()
    : _count(0)
    , _flag(1)
{
}

Object::Object(bool autodel)
    : _count(0)
    , _flag(0)
{
    setAutoDelete(autodel);
    if (!autodel)
    {
        _flag |= 2;
    }
}

Object::~Object() 
{
}

static BaseType::RTTIOfInfo* __stdcall BaseRTTIType()
{
    return NULL;
}

RTTIOfInfo Object::typeObject = {0, _U("Object"), BaseRTTIType, &Object::Create};

//String __stdcall Object::RTTIName()
//{
//    return RTTIType()->typeName;
//}
//
RTTIOfInfo* __stdcall Object::RTTIType()
{
    return &typeObject;
}

/*bool Object::IsShowObj()
{
    return ((_flag & 8) == 0);
}

void Object::ShowObj(bool bShow)
{
    if (bShow)
    {
        _flag &= ~8;
    }
    else
    {
        _flag |= 8;
    }
}*/

bool Object::InheritFrom(Object* other)
{
    return GetRTTIType()->InheritFrom(other->GetRTTIType());
}

//bool Object::EqualType(Object* other)
//{
//    return (GetRTTIType() == other->GetRTTIType());
//}

RTTIOfInfo* Object::GetRTTIType() const
{ 
    return &typeObject; 
}

Object* __stdcall Object::Create()
{
    return NULL;//new Object();
}

void Object::StaticInit()
{
}

const BaseType::MemberInfo* __stdcall Object::ClassMemberInfo()
{
    return NULL;
}

void Object::Dispose()
{

}

static int new_count = 0;
static int del_count = 0;


Object* Object::Clone()
{
    return NULL;
}

String Object::ToString()
{
    return String();
}

bool Object::ToBool() const
{
    return false;
}

float Object::ToFloat()
{
    return 0;
}

double Object::ToDouble()
{
    return ToFloat();
}

int32_t Object::ToInt()
{
    return 0;
}

int Object::GetHashCode()
{
    return static_cast<int>((unsigned long)this);
}

bool Object::Equals(Object* Other)
{
    if (this == Other)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool RTTIOfInfo::InheritFrom(RTTIOfInfo* baseType)
{
    if (baseType == NULL)
    {
        return false;
    }

    RTTIOfInfo* pTypeThis = this;

    while (pTypeThis != NULL)
    {
        if (pTypeThis == baseType)
        {
            return true;
        }

        pTypeThis = (*pTypeThis->baseType)();
    }

    return false;
}

bool RTTIOfInfo::IsInstanceOfType(Object* Other)
{
    return InheritFrom(Other->GetRTTIType());
}

bool Object::SetMember(const String& name, Object* val)
{
    bool bExist = true;
    ObjectPtr cachedObj(val);
    const MemberEntry* fcall = __FindMemberFunc(GetMemberInfo(), name);

    if (NULL != fcall && NULL != fcall->setfunc)
    {
        mmpf _mmf;
        _mmf.pf = fcall->setfunc;

        switch (fcall->type)
        {
        case UIDataType::IntType:
            (this->*_mmf.int_set_pf)(val->ToInt());
            break;

        case UIDataType::FloatType:
            (this->*_mmf.float_set_pf)(val->ToFloat());
            break;

        case UIDataType::BoolType:
            (this->*_mmf.bool_set_pf)(val->ToBool());
            break;

        case UIDataType::Uint32Type:
            (this->*_mmf.uint32_set_pf)((Uint32)val->ToInt());
            break;

        case UIDataType::StringType:
            (this->*_mmf.string_set_pf)(val->ToString());
            break;

        case UIDataType::PointType:
            (this->*_mmf.point_set_pf)(OPoint::FromObj(val));
            break;

        case UIDataType::RectType:
            (this->*_mmf.rect_set_pf)(ORect::FromObj(val));
            break;

        case UIDataType::SizeType:
            (this->*_mmf.size_set_pf)(OSize::FromObj(val));
            break;

        case UIDataType::ObjectType:
            (this->*_mmf.obj_set_pf)(val);
            break;

        case UIDataType::AttriType:
            bExist = (this->*_mmf.attri_set_pf)(name, val);
            break;

        default:
            bExist = false;
        }
    }
    else
    {
        bExist = false;
    }

    return bExist;
}

bool Object::GetMember(const String& name, ObjectPtr& retVal)
{
    bool bExist = true;
    const MemberEntry* fcall = __FindMemberFunc(GetMemberInfo(), name);

    if (NULL != fcall && fcall->getfunc != NULL)
    {
        mmpf _mmf;

        _mmf.pf = fcall->getfunc;

        switch (fcall->type)
        {
        case UIDataType::IntType:
            retVal = new Integer((this->*_mmf.int_get_pf)());
            break;

        case UIDataType::FloatType:
            retVal = new OFloat((this->*_mmf.float_get_pf)());
            break;

        case UIDataType::BoolType:
            retVal = BOOLTOBOOLEAN((this->*_mmf.bool_get_pf)());
            break;

        case UIDataType::Uint32Type:
            retVal = new Integer((this->*_mmf.uint32_get_pf)());
            break;

        case UIDataType::StringType:
            retVal = new OString((this->*_mmf.string_get_pf)());
            break;

        case UIDataType::PointType:
            retVal = new OPoint((this->*_mmf.point_get_pf)());
            break;

        case UIDataType::RectType:
            retVal = new ORect((this->*_mmf.rect_get_pf)());
            break;

        case UIDataType::SizeType:
            retVal = new OSize((this->*_mmf.size_get_pf)());
            break;

        case UIDataType::ObjectType:
            retVal = (this->*_mmf.obj_get_pf)();
            break;

        case UIDataType::AttriType:
            bExist = (this->*_mmf.attri_get_pf)(name, retVal);
            break;

        default:
            bExist = false;
        }
    }
    else
    {
        bExist = false;
    }

    return bExist;
}

}
